package top.callname.filter;

import java.io.IOException;
import java.io.StringReader;
import java.util.Date;

import javax.servlet.ServletInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.weixin4j.Configuration;
import org.weixin4j.WeixinException;
import org.weixin4j.model.message.InputMessage;
import org.weixin4j.model.message.MsgType;
import org.weixin4j.model.message.OutputMessage;
import org.weixin4j.spi.HandlerFactory;
import org.weixin4j.spi.IMessageHandler;
import org.weixin4j.spi.INormalMessageHandler;
import org.weixin4j.util.XStreamFactory;

import top.callname.bean.ConstanstBean;
import top.callname.bean.NoticeBean;
import top.callname.bean.RspInfoBean;
import top.callname.bean.StudentBean;
import top.callname.service.CourseService;
import top.callname.service.NoticeService;
import top.callname.service.SignService;
import top.callname.service.StudentService;
import top.callname.service.impl.CourseServiceImpl;
import top.callname.service.impl.NoticeServiceImpl;
import top.callname.service.impl.SignServiceImpl;
import top.callname.service.impl.StudentServiceImpl;

/**
 *  处理接收到的用户消息
 * @author 维康
 *
 */
public class WchatMessageHandler implements IMessageHandler {

	private static StudentService studentService = new StudentServiceImpl();
	private static SignService signService = new SignServiceImpl();
	private static CourseService courseService = new CourseServiceImpl();
	private static NoticeService noticeService = new NoticeServiceImpl();

	
	@Override
	public String invoke(ServletInputStream inputStream) throws WeixinException {
		try {
			String xmlMsg = XStreamFactory.inputStream2String(inputStream);
			if (Configuration.isDebug()) {
				System.out.println("获取POST的消息:");
				System.out.println(xmlMsg);
				System.out.println("------------------------");
			}
			return invoke(xmlMsg);
		} catch (IOException ex) {
			throw new WeixinException("输入流转换错误：", ex);
		}
	}

	@Override
	public String invoke(String inputXml) throws WeixinException {
		OutputMessage outputMsg = null;
		try {
			JAXBContext context = JAXBContext
					.newInstance(new Class[] { InputMessage.class });
			Unmarshaller unmarshaller = context.createUnmarshaller();
			InputMessage inputMsg = (InputMessage) unmarshaller
					.unmarshal(new StringReader(inputXml));
			if (Configuration.isDebug()) {
				System.out.println("将指定节点下的xml节点数据转换为对象成功!");
			}

			String msgType = inputMsg.getMsgType();
			if (Configuration.isDebug()) {
				System.out.println("POST的消息类型:[" + msgType + "]");
			}

			INormalMessageHandler normalMsgHandler = HandlerFactory
					.getNormalMessageHandler();
			
			//我们只需要用到文本类型的消息
			if (msgType.equals(MsgType.Text.toString())) {
				
				String content = inputMsg.getContent();
				String openid = inputMsg.getFromUserName();
				if(content.contains("学号@")){
					//根据学号来注册
					String stuNo = content.split("@")[1];
					//绑定微信
					RspInfoBean  rsp = studentService.bindWeixin(stuNo,openid );
					//返回消息
					inputMsg.setContent(rsp.getRspDesc());
					
				}else if(content.contains("课表") || content.contains("课程")){
					//课表查看
					RspInfoBean  rsp = courseService.getNowDayCourseTableByOpenid(openid);
					//返回消息
					inputMsg.setContent(rsp.getRspDesc());
					
				}else if(content.contains("公告") || content.contains("通告")){
					StudentBean student = studentService.getByOpenid(openid);
					//课表查看
					if(ConstanstBean.RSP_SUCCESS.equals(student.getRspCode())){
						NoticeBean notice = noticeService.getNewNoticeByCid(student.getCid());
						if(notice.getId()!=null){
							inputMsg.setContent(notice.getContent());
						}else{
							inputMsg.setContent("当前暂无公告！");
						}
					}else{
						inputMsg.setContent(student.getRspDesc());
					}
					
				}else{
					//根据老师生成的随机编码查询签到表，匹配成功则签到成功！
					//随机编码解析,必须为数字
					RspInfoBean rsp = signService.signIng(openid, content);
					//返回消息
					inputMsg.setContent(rsp.getRspDesc());
				}
				
				//回复消息
				outputMsg = normalMsgHandler.textTypeMsg(inputMsg
						.toTextInputMessage());
				
			} else{
				//回复消息
				inputMsg.setContent("暂不支持此类型类消息！");
				outputMsg = normalMsgHandler.textTypeMsg(inputMsg
						.toTextInputMessage());
			}
			
			/*else if (msgType.equals(MsgType.Image.toString())) {
				outputMsg = normalMsgHandler.imageTypeMsg(inputMsg
						.toImageInputMessage());
			} else if (msgType.equals(MsgType.Voice.toString())) {
				outputMsg = normalMsgHandler.voiceTypeMsg(inputMsg
						.toVoiceInputMessage());
			} else if (msgType.equals(MsgType.Video.toString())) {
				outputMsg = normalMsgHandler.videoTypeMsg(inputMsg
						.toVideoInputMessage());
			} else if (msgType.equals(MsgType.ShortVideo.toString())) {
				outputMsg = normalMsgHandler.shortvideoTypeMsg(inputMsg
						.toShortVideoInputMessage());
			} else if (msgType.equals(MsgType.Location.toString())) {
				outputMsg = normalMsgHandler.locationTypeMsg(inputMsg
						.toLocationInputMessage());
			} else if (msgType.equals(MsgType.Link.toString())) {
				outputMsg = normalMsgHandler.linkTypeMsg(inputMsg
						.toLinkInputMessage());
			} else if (msgType.equals(MsgType.Event.toString())) {
				String event = inputMsg.getEvent();

				IEventMessageHandler eventMsgHandler = HandlerFactory
						.getEventMessageHandler();

				if (event.equals(EventType.Click.toString())) {
					outputMsg = eventMsgHandler.click(inputMsg
							.toClickEventMessage());
				} else if (event.equals(EventType.View.toString())) {
					outputMsg = eventMsgHandler.view(inputMsg
							.toViewEventMessage());
				} else if (event.equals(EventType.Subscribe.toString())) {
					String eventKey = inputMsg.getEventKey();
					if ((eventKey != null) && (eventKey.startsWith("qrscene_"))) {
						outputMsg = eventMsgHandler.qrsceneSubscribe(inputMsg
								.toQrsceneSubscribeEventMessage());
					} else
						outputMsg = eventMsgHandler.subscribe(inputMsg
								.toSubscribeEventMessage());
				} else if (event.equals(EventType.Unsubscribe.toString())) {
					outputMsg = eventMsgHandler.unSubscribe(inputMsg
							.toUnSubscribeEventMessage());
				} else if (event.equals(EventType.Scan.toString())) {
					outputMsg = eventMsgHandler.qrsceneScan(inputMsg
							.toQrsceneScanEventMessage());
				} else if (event.equals(EventType.Location.toString())) {
					outputMsg = eventMsgHandler.location(inputMsg
							.toLocationEventMessage());
				} else if (event.equals(EventType.Scancode_Push.toString())) {
					outputMsg = eventMsgHandler.scanCodePush(inputMsg
							.toScanCodePushEventMessage());
				} else if (event.equals(EventType.Scancode_Waitmsg.toString())) {
					outputMsg = eventMsgHandler.scanCodeWaitMsg(inputMsg
							.toScanCodeWaitMsgEventMessage());
				} else if (event.equals(EventType.Pic_Sysphoto.toString())) {
					outputMsg = eventMsgHandler.picSysPhoto(inputMsg
							.toPicSysPhotoEventMessage());
				} else if (event
						.equals(EventType.Pic_Photo_OR_Album.toString())) {
					outputMsg = eventMsgHandler.picPhotoOrAlbum(inputMsg
							.toPicPhotoOrAlbumEventMessage());
				} else if (event.equals(EventType.Pic_Weixin.toString())) {
					outputMsg = eventMsgHandler.picWeixin(inputMsg
							.toPicWeixinEventMessage());
				} else if (event.equals(EventType.Location_Select.toString())) {
					outputMsg = eventMsgHandler.locationSelect(inputMsg
							.toLocationSelectEventMessage());
				}*/
			if (outputMsg != null) {
				setOutputMsgInfo(outputMsg, inputMsg);
			}
		} catch (IOException ex) {
			throw new WeixinException("输入流转换错误：", ex);
		} catch (NoSuchMethodException ex) {
			throw new WeixinException("没有找打对应方法：", ex);
		} catch (SecurityException ex) {
			throw new WeixinException("安全错误：", ex);
		} catch (Exception ex) {
			throw new WeixinException("系统错误：", ex);
		}
		if (outputMsg != null) {
			try {
				String xml = outputMsg.toXML();
				if (Configuration.isDebug()) {
					System.out.println("POST输出消息:");
					System.out.println(xml);
					System.out.println("------------------------");
				}
				return xml;
			} catch (Exception ex) {
				throw new WeixinException("转换回复消息为xml时错误：", ex);
			}
		}
		return "";
	}
	
	  private static void setOutputMsgInfo(OutputMessage oms, InputMessage msg)
			    throws Exception{
	    oms.setCreateTime(Long.valueOf(new Date().getTime()));
	    oms.setToUserName(msg.getFromUserName());
	    oms.setFromUserName(msg.getToUserName());
	  }
}
